﻿// ***********************************************************************
// Assembly         : Delta_util
// Author           : Juan Alberto Cerino Gomez
// Created          : 02-18-2013
//
// Last Modified By : Juan Alberto Cerino Gomez
// Last Modified On : 05-10-2013
// ***********************************************************************
// <copyright file="Encriptacion.cs" company="Delta Bussines">
//     Copyright (c) 2013  Delta Bussines. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using System.Runtime.InteropServices;

namespace Delta_util.Clases
{
    /// <summary>
    /// Clase que se usa para encriptar y desencriptar cadena de caracteres.
    /// </summary>
    public class Encriptacion
    {

        /// <summary>
        /// La llave base.
        /// </summary>
        protected string keyBase = "@admin$admin";
        /// <summary>
        /// La llava IV base.
        /// </summary>
        protected string ivBase = "@dministradorpkconfig";
        /// <summary>
        /// Indica si se usa las llaves bases.
        /// </summary>
        protected bool configBase = true;
        /// <summary>
        /// La key representada en bytes.
        /// </summary>
        byte[] _key;

        /// <summary>
        /// El ventor IV representado en bytes.
        /// </summary>
        byte[] _iv;


        /// <summary>
        /// Constructor de la clase.
        /// </summary>
        public Encriptacion()
        {
            _key =

            Encoding.ASCII.GetBytes(keyBase);

            _iv =

            Encoding.ASCII.GetBytes(ivBase);

        }

        /// <summary>
        /// Constructor de la clase que recibe las llaves que se usarán para realizar el proceso.
        /// </summary>
        /// <param name="key">La llave.</param>
        /// <param name="iv">El vector IV.</param>
        public Encriptacion(string key, string iv)
        {
            _key =

            Encoding.ASCII.GetBytes(key);

            _iv =

            Encoding.ASCII.GetBytes(iv);
            configBase = false;
        }

        /// <summary>
        /// Metodo que se encarga de revisar la longitud de la llave, si la llave no es de la misma longitud, se iguala la longitud al del algoritmo de encriptación.
        /// </summary>
        /// <param name="datos">Arreglo de bytes, que representa la llave.</param>
        /// <param name="enc">Algoritmo de encriptación.</param>
        /// <returns>Devuelve un valor(System.Byte[][]) que representa la llave corregida.</returns>
        protected byte[] arreglarKey(byte[] datos, RijndaelManaged enc)
        {
            enc.GenerateKey();
            if (datos.Length < enc.Key.Length)
                Array.Resize(ref datos, enc.Key.Length);
            return datos;


        }

        /// <summary>
        /// Metodo que se encarga de revisar la longitud del vector IV, si el vector IV no es de la misma longitud, se iguala la longitud al del algoritmo de encriptación.
        /// </summary>
        /// <param name="datos">Arreglo de bytes, que representa el vector IV.</param>
        /// <param name="enc">Algoritmo de encriptación.</param>
        /// <returns>Devuelve un valor(System.Byte[][]) que representa la llave corregida.</returns>
        protected byte[] arreglarIV(byte[] datos, RijndaelManaged enc)
        {
            enc.GenerateIV();
            if (datos.Length < enc.IV.Length)
                Array.Resize(ref datos, enc.IV.Length);
            return datos;


        }
        /// <summary>
        /// Metodo que se encarga de encriptar una cadena de caracteres.
        /// </summary>
        /// <param name="inputText">Texto a encriptar.</param>
        /// <returns>Devuelve el valor(System.String) encriptado.</returns>
        public string Encripta(string inputText)
        {

            byte[] inputBytes = Encoding.ASCII.GetBytes(inputText);

            byte[] encripted;

            RijndaelManaged cripto = new RijndaelManaged();
            _key = arreglarKey(_key, cripto);
            _iv = arreglarIV(_iv, cripto);
            using (MemoryStream ms =

                new MemoryStream(inputBytes.Length))
            {

                using (CryptoStream objCryptoStream =

                    new CryptoStream(ms,

                           cripto.CreateEncryptor(_key, _iv),

                           CryptoStreamMode.Write))
                {

                    objCryptoStream.Write(inputBytes, 0, inputBytes.Length);

                    objCryptoStream.FlushFinalBlock();

                    objCryptoStream.Close();

                }

                encripted = ms.ToArray();

            }

            return Convert.ToBase64String(encripted);

        }



        /// <summary>
        /// Metodo que se encarga de desencriptar una cadena de caracteres.
        /// </summary>
        /// <param name="inputText">Texto a desencriptar.</param>
        /// /// <param name="esWeb">Indica si la cadena proviene de una URL.</param>
        /// <returns>Devuelve el valor(System.String) desencriptado.</returns>
        public string Desencriptar(string inputText, bool esWeb = true)
        {

            if (esWeb)
                inputText = inputText.Replace(" ", "+");
            if (string.IsNullOrEmpty(inputText))
                return "";
            if (configBase)
                return "";
            byte[] inputBytes = Convert.FromBase64String(inputText);

            byte[] resultBytes = new byte[inputBytes.Length];

            string textoLimpio = String.Empty;

            RijndaelManaged cripto = new RijndaelManaged();
            _key = arreglarKey(_key, cripto);
            _iv = arreglarIV(_iv, cripto);

            using (MemoryStream ms = new MemoryStream(inputBytes))
            {

                using (CryptoStream objCryptoStream =

                new CryptoStream(ms, cripto.CreateDecryptor(_key, _iv),

                        CryptoStreamMode.Read))
                {

                    using (StreamReader sr =

                        new StreamReader(objCryptoStream, true))
                    {

                        textoLimpio = sr.ReadToEnd();

                    }


                }

            }

            return textoLimpio;


        }

    }
}


